package com.xiaolin.Thread.synchronization;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName SingletonTest
 * @Description 双重检查测试单例模式
 * @Detail 结合 volatile 与 synchronized
 *          volatile 防止指令重排序，创建对象分为3步：1、分配堆空间；2、初始化数据；3、将对象的地址指向变量，
 *          如果没有指令重排序，那么创建对象的步骤有可能变成1,、3、2，导致数据未初始化
 * @Author MyPC
 * @Date 2020/12/1
 * @Version 1.0
 */
public class SingletonTest {
    public static void main(String[] args) {
        // 开启一千个线程
        for (int i=0;i<1000;i++){
            new MyThread().start();
        }

    }
}

class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println(Stamp.getStamp().getName());
    }
}

class Stamp{
    private String name;

    public String getName() {
        return name;
    }
    // volatile 防止指令重排序
    private static volatile Stamp stamp;
    // 构造器私有
    private Stamp(String name){
        this.name=name;
    }

    public static Stamp getStamp(){
        if(stamp==null){
            // 将类锁住
            synchronized (Stamp.class){
                if(stamp==null){
                    stamp = new Stamp("小林");
                }
            }
        }
        return stamp;
    }
}
